package tool.zyk.protocol;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import lombok.extern.slf4j.Slf4j;
import tool.zyk.consts.RpcCommonConst;
import tool.zyk.consts.RpcOrderTypeEnum;
import tool.zyk.serializable.SerializableConverter;
import tool.zyk.serializable.SerializableFactory;
import tool.zyk.stardand.RpcRequest;
import tool.zyk.stardand.RpcResponse;
import tool.zyk.utils.LogUtil;

import java.util.List;

/**
 * author: zyk
 * datetime: 2024/1/31 22:51
 * describe: 字节解码器
 */
@Slf4j
public class ProtocolB2MDecoder extends ByteToMessageDecoder {


    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        try {
            in.retain();
            log.debug("decode");
            byte[] magicNum = new byte[RpcCommonConst.MAGIC_NUM.length];
            in.readBytes(RpcCommonConst.MAGIC_NUM.length).readBytes(magicNum);
            log.debug("解码 magicNum:{}", magicNum);
            long requestId = in.readLong();
            log.debug("解码 requestId:{}", requestId);
            int serializableType = in.readInt();
            log.debug("解码 serializableType:{}", serializableType);
            int orderType = in.readInt();
            log.debug("解码 orderType:{}", orderType);
            int dataLength = in.readInt();
            log.debug("解码 dataLength:{}", dataLength);
            byte[] dataByte = new byte[dataLength];
            in.readBytes(dataLength).readBytes(dataByte);
            SerializableConverter serializableConverter = SerializableFactory.getSerializableConverter(serializableType);
            RpcOrderTypeEnum byOrderType = RpcOrderTypeEnum.findByOrderType(orderType);
            switch (byOrderType) {
                case REQUEST:
                    RpcRequest rpcRequest = serializableConverter.serialRpcRequest(dataByte);
                    out.add(rpcRequest);
                    break;
                case RESPONSE:
                    RpcResponse rpcResponse = serializableConverter.serialRpcResponse(dataByte);
                    out.add(rpcResponse);
                    break;
            }
        } catch (Throwable throwable) {
            LogUtil.printErrorLog(throwable);
            throw new RuntimeException(throwable);
        }

    }
}
